package base;

public class Segment {
	public Point debut;
	public Point fin;

	public Segment(Point debut, Point fin) {
		super();
		this.debut = debut;
		this.fin = fin;			
	}

	@Override
	public String toString() {
		return "[" + debut + ", " + fin + "]";
	}

	public int superHashCode() {
		return super.hashCode();
	}

	public Segment trie() {
		assert !debut.equals(fin);
		if (debut.y > fin.y || (debut.y==fin.y && debut.x<=fin.x))
			return new Segment(debut,fin);
		else
			return new Segment(fin,debut);

	}

	public Point intersectionHorizontale(float y) {
		if ((debut.y - y) * (fin.y - y) > 0)
			return null;
		else if (debut.y == fin.y)
			return null;
		else {
			float x = ((fin.y - y) * debut.x + (y - debut.y))
					/ (fin.y - debut.y);
			return new Point(x, y);
		}
	}
	
	public Point homothetie(float lambda){
		return new Segment(debut.homothetie(lambda),fin.homothetie(lambda));
	}
	
	public Point intersectionDemiDroiteHorizontale(Point p){
		Point pointHorizon = new Point(p.x+1 + p.x/2, p.y);
		Segment demoHorizon = new Segment(p,pointHorizon);
		
		if(produitVectoriel(demoHorizon) == 0)
			return null;
		else{
			float lambda = produitVectoriel(new Segment(debut,p)) / produitVectoriel(demoHorizon);
			return p.translation(demoHorizon.homothetie(lambda));
		}
		
		return null;
	}
	
	public float tailleSegment(){
		return this.produitScalaire(this);
	}

	public float produitVectoriel(Segment s) {
		return (fin.x - debut.x) * (s.fin.y - s.debut.y) - (fin.y - debut.y)
				* (s.fin.x - s.debut.x);
	}

	public float produitScalaire(Segment s) {
		return (fin.x - debut.x) * (s.fin.x - s.debut.x) + (fin.y - debut.y)
				* (s.fin.y - s.debut.y);
	}

	public Point intersection(Segment s) {
		if (s.produitVectoriel(this) == 0)
			return null;

		float a = (s.produitVectoriel(new Segment(debut, s.debut)))
				/ s.produitVectoriel(this);

		if (a < 0 || a > 1)
			return null;
		else
			return new Point(debut.x + a * (fin.x - debut.x), debut.y + a
					* (fin.y - debut.y));
	}

	public boolean contains(Point p){
		Segment s = new Segment(debut,p);
		return (
				produitVectoriel(s) == 0 
				&& produitScalaire(s) >= 0
				&& this.tailleSegment() <= produitScalaire(this)
				);
	}
}
